package com.gomcarter.frameworks.base.config;

import com.gomcarter.frameworks.base.context.SpringContextHolder;
import com.gomcarter.frameworks.base.converter.jackson.CustomMappingJacksonConverter;
import com.gomcarter.frameworks.base.cross.CrossAccessFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.util.unit.DataSize;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.FormContentFilter;

import javax.annotation.Resource;
import javax.servlet.MultipartConfigElement;
import java.util.Collections;

/**
 * 基础配置
 */
@Configuration
@EnableConfigurationProperties(BaseConfProperties.class)
public class BaseConfiguration {

    @Resource
    private CharacterEncodingFilter characterEncodingFilter;

    @Bean
    public BaseRespAdvice baseRespAdvice() {
        return new BaseRespAdvice();
    }

    @Bean
    public BaseMvcConfigurer baseViewController(BaseConfProperties baseConfProperties,
                                                @Autowired(required = false) CustomMappingJacksonConverter customMappingJacksonConverter) {
        return new BaseMvcConfigurer(baseConfProperties, customMappingJacksonConverter);
    }

    @Bean
    public SpringContextHolder springContextHolder() {
        return new SpringContextHolder();
    }

    /**
     * 设置字符编码器,避免post形式的form表单出中文乱码
     */
    @Bean
    @ConditionalOnMissingBean
    public FilterRegistrationBean<CharacterEncodingFilter> customCharacterEncodingFilter() {
        FilterRegistrationBean<CharacterEncodingFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(characterEncodingFilter);
        filterRegistrationBean.setUrlPatterns(Collections.singleton("/*"));
        filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return filterRegistrationBean;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = BaseConfConst.BASE_CONFIG_PREFIX, name = "cross-enabled", havingValue = "true", matchIfMissing = true)
    public CrossAccessFilter crossAccessFilter(BaseConfProperties baseConfProperties) {
        return new CrossAccessFilter(baseConfProperties.getAppendAllowHeaders());
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = BaseConfConst.BASE_CONFIG_PREFIX, name = "form-enabled", havingValue = "true", matchIfMissing = true)
    public FormContentFilter httpPutFormContentFilter() {
        return new FormContentFilter();
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = BaseConfConst.BASE_CONFIG_PREFIX, name = "multi-file-enabled", havingValue = "true")
    public MultipartConfigElement multipartConfigElement(BaseConfProperties baseConfProperties) {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        // 单个文件数据量:默认2M
        Integer maxFileSize = baseConfProperties.getMaxFileSize() == null ? 1024 * 2 : 1024 * baseConfProperties.getMaxFileSize();
        factory.setMaxFileSize(DataSize.ofKilobytes(maxFileSize));
        // 总上传数据量:默认6M
        Integer maxRequestFileSize = baseConfProperties.getMaxRequestSize() == null ? 1024 * 6 : 1024 * baseConfProperties.getMaxRequestSize();
        factory.setMaxRequestSize(DataSize.ofKilobytes(maxRequestFileSize));
        return factory.createMultipartConfig();
    }
}
